#include <all_wlib.h>
#pragma hdrstop
//#pragma package(smart_init)
#pragma resource "*.dfm"
#pragma link "HWindow"
#pragma link "ozf_Base"
#pragma link "HRectButton"
#pragma link "HSpacer"
#pragma link "HExcept"
#pragma link "HCFGStorage"

#include "oz_Main.h"

TMainForm      *MainForm;
HWND            MainWindow;
PHStorageLink   Opt;

typedef bool (*FormCB)( TForm *Owner, int doShow );
static FormCB OziForms[] = { SwitchTrack, SwitchTest, SwitchCompas, SwitchSpeed };

static BOOL inited = FALSE;
static MyValArray<TOziEvent> OziEvents;

//---------------------------------------------------------------------------
static octConnectType ConnectType = octNone;

bool OziConnected( void )
  {
 return OziInited() && ConnectType != octNone;
}

void OziDisconnect( void )
  {
     switch( ConnectType ) {
       case  octOzi:
                 break;

       case octFile:
                 break;


       case octPort:
                 break;
     }
     oziStopMM();
     MainForm->btnConnect->Down = false;
     ConnectType = octNone;
}

void OziConnect( void )
  {  octConnectType ct = (octConnectType)GOPT( "Connect/Type", octOzi );

     if ( !OziInited() )
       return;

     OziDisconnect();

     switch( ct ) {
       case  octOzi: if ( oziStartMMserial() )
                       return;
                 break;

       case octFile: if ( oziStartMMapi() )
                       return;
                 break;

       case octPort: if ( oziStartMMapi() )
                       return;
                 break;

            default: return;
     }
     ConnectType = ct;
     MainForm->btnConnect->Down = true;
}

void OziConnectProcess( void )
  {
     if ( !OziConnected() )
       return;

     switch( ConnectType ) {
       case  octOzi:
                 return;

       case octFile:
                 break;


       case octPort:
                 break;
     }
}
//---------------------------------------------------------------------------
void CALLBACK idOZIPos(double Lat,double Lon,double Speed,double Head,double Mag,double Alt )
  {  int E, N;
     ozi2UTM( Lat, Lon, E, N );

     for( int n = 0; n < OziEvents.Count(); n++ )
       OziEvents[n]( Lat, Lon, Speed, Head, Mag, Alt, E, N );
}

void OziRegisterEvent( TOziEvent ev )
  {
    if ( OziEvents.IndexOf(ev) == -1 )
      OziEvents.Add( ev );
}

void OziUnregisterEvent( TOziEvent ev )
  {
    OziEvents.Delete( ev );
}

BOOL OziInited( void )
  {
 return inited;
}

void OziInit( void )
  {
     BOOL isOzi = oziFindOzi() == 0;

     if ( inited != isOzi ) {
       if ( isOzi ) {
         oziSendMMpositionON( idOZIPos );
       }
     }
     inited = isOzi;
}

void OziClose( void )
  {
     oziSendMMpositionOFF();
     oziCloseApi();
}

//---------------------------------------------------------------------------
__fastcall TMainForm::TMainForm(TComponent* Owner)
    : TOziBaseForm( Owner )
  {
     if ( !LoadOziApiDll() )
       HAbort( "Cannot load OZI api library" );

     Opt = new HStorageLink;
       Opt->Storage = cfg;
       Opt->KeyPath = "";

     cfg->Load();

//CFG
     Init( "Main", (TForm**)&MainForm );
     client->BorderTop->Size = GOPT( "TitleHeight", client->BorderTop->Size );

//Set
     timerTimer(NULL);
}

void __fastcall TMainForm::WndProc( Messages::TMessage &m )
  {
     if ( m.Msg >= WM_USER && m.Msg < WM_USER+ARRAY_SIZE(OziForms) ) {
       OziForms[ m.Msg-WM_USER ]( this,true );
     } else
     if ( m.Msg == WM_USER+1024 ) {
       BringToFront();
     } else
       TOziBaseForm::WndProc( m );
}

//---------------------------------------------------------------------------
void __fastcall TMainForm::FormClose(TObject *Sender, TCloseAction &Action)
  {
    TOziBaseForm::FormClose( Sender, Action );

  //Forms
    for( int n = 0; n < ARRAY_SIZE(OziForms); n++ )
      OziForms[n]( this, FALSE );

  //CFG
    cfg->Save();

  //API
    OziClose();
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::timerTimer(TObject *Sender)
  {
    OziInit();
    if ( !OziInited() ) {
      SetCaption( "OZM: Waiting for OziExplorer..." );
      return;
    }

    if ( OziConnected() )
      SetCaption( "OZM: Run, Connected" );
     else
      SetCaption( "OZM: Run, Disconnected" );

    OziConnectProcess();
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::idFormSwitch(TObject *Sender)
  {  TSpeedButton *b = dynamic_cast<TSpeedButton*>(Sender);
     OziForms[ b->Tag ]( this,-1 );
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::idOnButton( TObject *Sender, const PHCustomWindowBorder Border, const HCaptionButton_t Button)
  {
     if ( Button == hcbHelp )
       Configure( this );
     TOziBaseForm::idOnButton( Sender, Border, Button );
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::FormCreate(TObject *Sender)
  {
    MainWindow = Handle;
    TOziBaseForm::FormCreate(Sender);
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift)
  {
     if ( Shift == (TShiftState() << ssCtrl) && Key == 'F' )
       Configure( this );
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::btnConnectClick(TObject *Sender)
  {
     if ( OziConnected() ) {
       OziDisconnect();
       btnConnect->Down = false;
     } else
       OziConnect();
}
//---------------------------------------------------------------------------
